package cn.wlinker.video.monitor.brand.hikversion.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import cn.wlinker.video.monitor.brand.hikversion.enums.EZOpenRequestEnum;
import cn.wlinker.video.monitor.domain.dto.MonitorDeviceDTO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 萤石云请求工具类
 *
 * @author gxsjx
 * @version 1.0
 * @date 2022/11/9
 */
@Component
public class EZOpenRequestUtils {

    private static String appKey;

    private static String appSecret;

    @Value("${hik-config.ezOpen.appKey}")
    public void setAppKey(String key) {
        appKey = key;
    }

    @Value("${hik-config.ezOpen.appSecret}")
    public void setAppSecret(String secret) {
        appSecret = secret;
    }


    public static Map<String, Object> initParamMapWithToken() {
        HashMap<String, Object> params = new HashMap<>();
        params.put("accessToken", EZOpenRequestUtils.HKGetAccessToken());
        return params;
    }

    public static Map<String, Object> initParamMapWithToken(MonitorDeviceDTO monitorDeviceDTO) {
        Map<String, Object> params = initParamMapWithToken();
        params.put("deviceSerial", monitorDeviceDTO.getDeviceCode());
        params.put("channelNo", monitorDeviceDTO.getChannelNo());
        return params;
    }

    /**
     * 发送http请求
     *
     * @param url
     * @param params
     * @return
     */
    public static Optional<JSONObject> requestAndGetAll(String url, Map<String, Object> params) {
        String post = HttpUtil.post(url, params);
        JSONObject jsonObject = JSONUtil.parseObj(post);
        String code = (String) jsonObject.get("code");
        if ("200".equals(code)) {
            return Optional.of(jsonObject);
        } else {
            StaticLog.warn(StrUtil.toString(jsonObject.get("msg")));
            //60000 设备不支持云台控制
            //60020 不支持该命令
            if ("60000".equals(code) || "60020".equals(code)) {
                throw new UnsupportedOperationException("设备不支持");
            }
            throw new RuntimeException(code + "," + StrUtil.toString(jsonObject.get("msg")));
        }
    }

    /**
     * 发送http请求
     *
     * @param url
     * @param params
     * @return
     */
    public static Optional<JSONObject> requestAndGetData(String url, Map<String, Object> params) {
        Optional<JSONObject> jsonObjectOptional = requestAndGetAll(url, params);
        if (!jsonObjectOptional.isPresent()) {
            return Optional.empty();
        }
        JSONObject jsonObject = jsonObjectOptional.get();
        JSONObject data = JSONUtil.parseObj(JSONUtil.toJsonStr(jsonObject.get("data")));
        return Optional.of(data);
    }

    /**
     * 获取萤石云的accessToken
     *
     * @return
     */
    public static String HKGetAccessToken() {
        String token = null;
        HashMap<String, Object> map = new HashMap<>();
        map.put("appKey", appKey);
        map.put("appSecret", appSecret);
        Optional<JSONObject> jsonObject = EZOpenRequestEnum.GET_TOKEN.requestAndGetData(map);
        if (jsonObject.isPresent()) {
            JSONObject data = jsonObject.get();
            token = (String) data.get("accessToken");
        }
        StaticLog.debug("获取到的token --> {}", token);
        return token;
    }

    /**
     * 自动加密直播
     *
     * @param dto 监控的配置信息
     */
    public static void autoCloseLive(MonitorDeviceDTO dto) {
        if (dto.getLiveClose() != null && dto.getLiveClose() != 0) {
            return;
        }
        Map<String, Object> params = initParamMapWithToken();
        params.put("source", dto.getDeviceCode().toUpperCase() + ":" + dto.getChannelNo());
        Optional<JSONObject> jsonObjectOptional = EZOpenRequestEnum.CLOSE_LIVE.requestAndGetAll(params);
        //解析数据。如果关闭成功打印
        if (!jsonObjectOptional.isPresent()) {
            return;
        }
        JSONObject res = jsonObjectOptional.get();
        Object data = res.get("data");
        if (!(data instanceof JSONArray)) {
            return;
        }
        JSONArray dataArray = (JSONArray) data;
        for (Object dataItem : dataArray) {
            JSONObject jsonObject = JSONUtil.parseObj(String.valueOf(dataItem));
            if (!"200".equals(jsonObject.get("ret")) && !"60063".equals(jsonObject.get("ret"))) {
                continue;
            }
            String deviceSerial = (String) jsonObject.get("deviceSerial");
            Integer channelNo = (Integer) jsonObject.get("channelNo");
            StaticLog.info("关闭设备{}的通道{}成功", deviceSerial, channelNo);
        }
    }

}
